package com.tank.demo.facadeAndMediator;

import com.tank.demo.abstractFactory.*;
import com.tank.demo.chainOfResponsibility.Collider;
import com.tank.demo.chainOfResponsibility.ColliderChain;
import com.tank.demo.decorator.WhiteFrameDecorator;
import com.tank.demo.myenum.DirEnum;
import com.tank.demo.myenum.TankGroupEnum;
import com.tank.demo.strategy.FireStrategy;
import com.tank.demo.utils.PropertyMgr;
import com.tank.demo.utils.ResourceMgr;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.apache.lucene.util.ArrayUtil;
import org.omg.PortableInterceptor.INACTIVE;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static com.tank.demo.utils.PropertyMgr.getInstance;

/**
 * GameModel专门处理游戏逻辑
 * 门面模式：抽离TankFrame和逻辑类群的交互
 * 调停者模式：解耦坦克、子弹、爆炸、墙等交互
 */
@Data
@AllArgsConstructor
@ToString
public class GameModel {
    private static final GameModel INSTANCE = new GameModel();
    static {
        INSTANCE.initialize();
    }
    public static final int GAME_WIDTH = Integer.parseInt(PropertyMgr.getInstance().getKey("WIDTH")), GAME_HEIGHT = Integer.parseInt(PropertyMgr.getInstance().getKey("HEIGHT"));
    public static BaseGameAbstractFactory gameAbstractFactory;
    public static BaseTank myTank;
    ColliderChain chain = new ColliderChain();

    public List<BaseGameObject> bgo = new ArrayList<>();

    {
        try {
            gameAbstractFactory = (BaseGameAbstractFactory) Class.forName(PropertyMgr.getInstance().getKey("gameAbstractFactory")).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void add(BaseGameObject bgo){
        this.bgo.add(bgo);
    }
    public void remove(BaseGameObject bgo){
        this.bgo.remove(bgo);
    }

    public void initialize(){
        //初始化主战坦克
        myTank = gameAbstractFactory.createTank(540, 600, DirEnum.UP, false, TankGroupEnum.RED);

        //初始化敌方坦克
        for (int i = 0; i < Integer.parseInt(PropertyMgr.getInstance().getKey("enemyTanksSize")); i++) {
            add(gameAbstractFactory.createTank(100 + i * 150, 200, DirEnum.DOWN, false, TankGroupEnum.BLUE));
        }

        //初始化墙
        initWall(150,300,6,true);
        initWall(690,300,6,true);
        initWall(750,500,4,false);
        initWall(380,500,4,false);
    }


    /**
     * 初始化墙的方法
     * @param x 墙的横坐标
     * @param y 墙的纵坐标
     * @param length 墙的个数
     * @param isHorizontal （true:横向 /false：纵向）
     */
    private void initWall(int x,int y,int length,boolean isHorizontal){
        int width = ResourceMgr.wall.getWidth();
        int height = ResourceMgr.wall.getHeight();
        if (isHorizontal){
            for (int i = 0;i<length;i++){
                add(gameAbstractFactory.createWall(x+i*width,y));
            }
        }else {
            for (int i = 0;i<length;i++){
                add(gameAbstractFactory.createWall(x,y+i*height));
            }
        }

    }
    public static GameModel getInstance(){
        return INSTANCE;
    }

    private GameModel() {

    }

    public void paint(Graphics g) {

        //白框装饰
//        myTank.paint(g);
        new WhiteFrameDecorator(Arrays.asList(myTank)).paint(g);

//        //增强for使用的是集合内部迭代器，迭代器遍历的时候会加锁，不允许外部对遍历元素进行操作
//        for (int i = 0; i < bgo.size(); i++) {
//            bgo.get(i).paint(g);
//        }
        new WhiteFrameDecorator(bgo).paint(g);


        //责任链模式碰撞器
        for (int i = 0; i < bgo.size(); i++) {
            for (int j = i+1; j < bgo.size(); j++) {
                BaseGameObject o1 = bgo.get(i);
                BaseGameObject o2 = bgo.get(j);
                chain.collide(o1,o2);
            }
        }


    }
}
